package com.grapro.visitorsystem.config.exception;

import com.grapro.visitorsystem.constant.ExceptionConst;
import com.grapro.visitorsystem.utils.json.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@RestControllerAdvice //该注解将异常以json格式输出
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired
    private ExceptionConst excConst;

    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    public JsonUtil defaultErrorHandler(Exception ex) {
        if (ex instanceof HttpRequestMethodNotSupportedException) {

        } else if (ex instanceof HttpMediaTypeNotSupportedException) {
            status = HttpStatus.UNSUPPORTED_MEDIA_TYPE;
            return this.handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException)ex, headers, status, request);
        } else if (ex instanceof HttpMediaTypeNotAcceptableException) {
            status = HttpStatus.NOT_ACCEPTABLE;
            return this.handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException)ex, headers, status, request);
        } else if (ex instanceof MissingPathVariableException) {
            status = HttpStatus.INTERNAL_SERVER_ERROR;
            return this.handleMissingPathVariable((MissingPathVariableException)ex, headers, status, request);
        } else if (ex instanceof MissingServletRequestParameterException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleMissingServletRequestParameter((MissingServletRequestParameterException)ex, headers, status, request);
        } else if (ex instanceof ServletRequestBindingException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleServletRequestBindingException((ServletRequestBindingException)ex, headers, status, request);
        } else if (ex instanceof ConversionNotSupportedException) {
            status = HttpStatus.INTERNAL_SERVER_ERROR;
            return this.handleConversionNotSupported((ConversionNotSupportedException)ex, headers, status, request);
        } else if (ex instanceof TypeMismatchException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleTypeMismatch((TypeMismatchException)ex, headers, status, request);
        } else if (ex instanceof HttpMessageNotReadableException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleHttpMessageNotReadable((HttpMessageNotReadableException)ex, headers, status, request);
        } else if (ex instanceof HttpMessageNotWritableException) {
            status = HttpStatus.INTERNAL_SERVER_ERROR;
            return this.handleHttpMessageNotWritable((HttpMessageNotWritableException)ex, headers, status, request);
        } else if (ex instanceof MethodArgumentNotValidException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleMethodArgumentNotValid((MethodArgumentNotValidException)ex, headers, status, request);
        } else if (ex instanceof MissingServletRequestPartException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleMissingServletRequestPart((MissingServletRequestPartException)ex, headers, status, request);
        } else if (ex instanceof BindException) {
            status = HttpStatus.BAD_REQUEST;
            return this.handleBindException((BindException)ex, headers, status, request);
        } else if (ex instanceof NoHandlerFoundException) {
            status = HttpStatus.NOT_FOUND;
            return this.handleNoHandlerFoundException((NoHandlerFoundException)ex, headers, status, request);
        } else if (ex instanceof AsyncRequestTimeoutException) {
            status = HttpStatus.SERVICE_UNAVAILABLE;
            return this.handleAsyncRequestTimeoutException((AsyncRequestTimeoutException)ex, headers, status, request);
        } else {
            throw ex;
        }
    }

    /*public JsonResult defaultErrorHandler(Exception e){

        System.out.println("NZQ－－－－defaultErrorHandler");

        // 1. 方法不被允许
        if(e instanceof HttpRequestMethodNotSupportedException){
            return JsonUtil.error(excConst.HTTP_METHOD_ERROR_CODE, excConst.HTTP_METHOD_ERROR);
        }

        // 2. 未找到对应处理方法
        if(e instanceof NoHandlerFoundException){
            return JsonUtil.error(excConst.NO_METHOD_CODE, excConst.NO_METHOD);
        }

        // 3. 自定义错误异常
        if(e instanceof CustomException){
            return JsonUtil.error(((CustomException)e).getCode(),((CustomException)e).getMessage());
        }

        // 4. 认证失败
        if (e instanceof AuthenticationException || e instanceof AccessDeniedException) {
            return JsonUtil.error(excConst.NO_AUTHORITY_CODE, excConst.NO_AUTHORITY);
        }

        //　5. 请求错误
        if (e instanceof MethodArgumentNotValidException) {
            return JsonUtil.error(excConst.HTTP_METHOD_ERROR, excConst.HTTP_METHOD_ERROR_CODE);
        }

        // 6. 您的登录状态已失效

        // 7. 数据库操作异常
        if (e instanceof SQLException) {
            return JsonUtil.error(excConst.SQL_ERROR_CODE, excConst.SQL_ERROR);
        }

        // 8. 内部服务器错误
        return JsonUtil.error(excConst.UNKNOW_CODE, excConst.UNKNOW);
    }*/

}